<template>
	<view :style="pageStyle">
		<view class="bg-transparent height-p-100">
			<!--有数据-->
			<view class="height-p-100" v-if="list.length > 0">
				<!--列表插槽-->
				<slot name="render"></slot>
				<!--列表底部提示-->
				<view class="padding-bottom padding-top-xxl text-center">
					<u-loadmore bg-color="rgba(0, 0, 0, 0)" :is-dot="false" :font-size="30" :status="status" :load-text="bottomLoadText" />
				</view>
			</view>
			<!--无数据-->
			<view v-else>
				<view v-if="customEmpty">
					<slot name="empty"></slot>
				</view>
				<view v-else class="padding-top-xxl bg-transparent height-p-100">
					<u-empty v-if="isLoad" :width="400" :height="400" :text-size="30" mode="search" text="加载中">
					</u-empty>
					<u-empty v-else :mode="emptyMode" :width="400" :height="400" :text-size="30" :icon="emptyIcon" text="暂无数据"></u-empty>
				</view>
			</view>

		</view>
	</view>
</template>

<script>
	import {
		LoadEnum
	} from "./config"
	/**
	 * author: wakin
	 * @description: 通用列表渲染子组件
	 * @createTime: 2021-11-17 1:28:18 ?F10: PM?
	 */
	export default {
		name: 'wakin-list-temp',
		props: {
			pageNumKey: {
				type: String,
				default: 'page',
			},
			pageSizeKey: {
				type: String,
				default: 'limit',
			},
			pageStyle: {
				type: String,
				default: ''
			},
			height: {
				type: [Number, String],
				default: '100%'
			},
			// 是否显示加载中toast
			showLoadToast: {
				type: Boolean,
				default: false
			},
			// 底部加载文字
			bottomLoadText: {
				type: Object,
				default: () => {
					return {
						loadmore: '轻轻上拉',
						loading: '努力加载中',
						nomore: '没有数据了'
					};
				}
			},
			// 默认空提示时使用的icon
			emptyMode: {
				type: String,
				default: "data"
			},
			// 默认空提示时使用的icon
			emptyIcon: {
				type: String,
				default: "", // require('./images/search.png')
			},
			// 是否使用自定义空提示
			customEmpty: {
				type: Boolean,
				default: false
			},
			statusCode: {
				type: Number,
				default: 200
			}
		},
		data() {
			return {
				list: [], // 列表数组
				status: 'loading', // loading:加载中 loadmore:加载更多 nomore:没有更多了
				total: 0, // 数据总数
				isLoad: true, // 加载中
			};
		},
		watch: {
			isLoad: {
				deep: true,
				immediate: true,
				handler(nval, oval) {
					// 组件数据加载状态
					this.$emit('loadStatus', nval);
					if (nval) {
						if (this.showLoadToast) this.$loadToast();
					} else {
						uni.hideLoading();
						uni.stopPullDownRefresh();
					}
					this.loadStatus();
				}
			}
		},
		methods: {
			/**
			 * @description 加载数据列表
			 * @param {String} loadType 加载类型 => load:首次/重新加载,bottom:触底(上滑)加载
			 * @param {Object} search 搜索条件
			 * @param {Boolean} debounce 开启防抖
			 * @param {Number} time 防抖时间
			 * @param {Function} api 接口
			 */
			async loadDatas({
				loadType = LoadEnum.load,
				search,
				debounce = false,
				time = 1000,
				api
			}) {
				// 搜索防抖
				if (debounce) {
					this.$u.debounce(
						async () => {
								await this._loadDatas(loadType, search, api);
							},
							time,
							false
					);
				}
				// 加载
				else {
					this._loadDatas(loadType, search, api);
				}
			},
			// 加载状态判断
			loadStatus() {
				if (this.isLoad) {
					this.status = 'loading';
				} else {
					this.status = this.list.length < this.total ? 'loadmore' : 'nomore';
				}
			},
			async _loadDatas(loadType, search, api) {
				this.isLoad = loadType === LoadEnum.load || this.list.length < this.total;
				switch (loadType) {
					case LoadEnum.load:
						// search.pageNum = 1;
						search[this.pageNumKey] = 1;
						this.list = [];
						// setTimeout(async () => {
						try {
							await api(search).then(res => {
								if (res.code === this.statusCode) {
									this.total = res.count ?? res.total ?? res.data.total;
									if (Array.isArray(res.data)) this.list = res.data;
									else this.list = res.rows || res.data.rows;
								} else {
									this.$toast(res.msg);
								}
								this.$emit('loadData', this.list, this.total, res);
							})
						} catch (err) {
							console.error("wakin-list-temp-error:", err);
						}
						this.isLoad = false;
						// }, 1000);
						break;
					case LoadEnum.bottom:
						if (this.list.length < this.total) {
							// search.pageNum = ++search.pageNum;
							search[this.pageNumKey] = ++search[this.pageNumKey];
							try {
								await api(search).then(res => {
									let list = [];
									if (res.code === this.statusCode) {
										// this.total = res.total;
										this.total = res.count ?? res.total ?? res.data.total;
										if (Array.isArray(res.data)) list = res.data;
										else list = res.rows || res.data.rows;
										// let list = res.data;
										this.list = [...this.list, ...list];
									} else {
										this.$toast({
											msg: res.msg || res.message
										});
									}
									this.$emit('loadData', this.list, this.total, res);
								});
							} catch (err) {
								//TODO handle the exception
								console.error("wakin-list-temp-error:", err);
							}
							this.isLoad = false;
						}
						break;
					default:
						this.isLoad = false;
						break;
				}
			}
			// search(e) {
			// 	this.list = this.list.filter(m => m.title.includes(e));
			// }
		}
	};
</script>

<style scoped>
	::v-deep .u-loadmore__content__text {
		line-height: unset !important;
	}
</style>
